#include "serializer.h"

namespace Pdf
{
	Serializer::Serializer(std::ostream &output) : output(output), delimiter( true )
	{   }

	void Serializer::visited(Integer *obj)
	{   
        if ( !delimiter )
            output << " ";

        output << obj->get();
        delimiter = false;
    }

	void Serializer::visited(Real *obj)
	{   
        if ( !delimiter )
            output << " ";

        output << obj->get();
        delimiter = false;
    }

	void Serializer::visited(Keyword *obj)
	{   
        if ( !delimiter )
            output << " ";

        output << obj->get();
        delimiter = false;
    }

	void Serializer::visited(Comment *obj)
	{   
        output << "%" << obj->get() << std::endl;    
        delimiter = true;
    }

	void Serializer::visited(Name *obj)
	{   
        output << "/" << obj->get();
        delimiter = false;
    }

	void Serializer::visited(String *obj)
	{  
        output << "(";
        String::Value value = obj->get();
        for (String::Value::const_iterator i = value.begin(), end = value.end(); i != end; ++i)
        {
            switch (*i)
            {
            case '\n':
                output << "\\n";
                break;
            case '\r':
                output << "\\r";
                break;
            case '\t':
                output << "\\t";
                break;
            case '\b':
                output << "\\b";
                break;
            case '\f':
                output << "\\f";
                break;
            case '\\':
                output << "\\\\";
                break;
            case '(':
                output << "\\(";
                break;
            case ')':
                output << "\\)";
                break;
            default:
                output << *i;
            }
        }
        output << ")";
        delimiter = true;
    }

	void Serializer::visited(Array *obj)
	{
		output << "[";
        delimiter = true;
		for (Array::Iterator i = obj->begin(), end = obj->end(); i != end; ++i)
			if (*i != 0)
				(*i)->apply( this );
		output << "]";
        delimiter = true;
	}

    void Serializer::visited(Names *obj)
    {
        output << "{";
        delimiter = true;
        for (Array::Iterator i = obj->begin(), end = obj->end(); i != end; ++i)
            if (*i != 0)
                (*i)->apply( this );
        output << "}";
        delimiter = true;
    }

	void Serializer::visited(Dictionary *obj)
	{
		output << "<<";
        delimiter = true;
		for (Dictionary::Iterator i = obj->begin(), end = obj->end(); i != end; ++i)
			if (i->second != 0)
			{
				output << "/" << i->first;
                delimiter = false;
				i->second->apply( this );
			}
        output << ">>";
        delimiter = true;
	}

	void Serializer::visited(Reference *obj)
	{   
        if ( !delimiter )
            output << " ";

        output << obj->get().id << " " << obj->get().gen << " R";
        delimiter = false;
    }
}